import axios, { AxiosRequestHeaders, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { useUserStore } from "../store/user";
import { layer } from '@layui/layui-vue';
import router from '../router'

type TAxiosOption = {
    timeout: number;
    baseURL: string;
}
 
const config: TAxiosOption = {
    timeout: 50000,
    baseURL: "http://localhost:8001"
}
 
class Http {
    service;
    constructor(config: TAxiosOption) {
        this.service = axios.create(config)

        /* 请求拦截 */
        this.service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
            const userInfoStore = useUserStore();
						//如果token存在
            if (userInfoStore.token) {
							//as代表跟TypeScript编译器知道它代表什么类型
							//从store中获取token并存到headers中，后面服务器就可以用这个token去验证用户信息
              (config.headers as AxiosRequestHeaders).Authorization = userInfoStore.token as string
            } 
						else {
							//Vue路由的路径(router.currentRoute.value.path)
							//如果token不存在，并且Vue路由的路径不是登录页，则跳转到登录页
							if(router.currentRoute.value.path!=='/login') {
									router.push('/login');
							}
            }
            return config
        }, error => {
						//拦截器通常会返回一个Promise，解析(resolve)、拒绝(reject)
            return Promise.reject(error);
        })

        /* 响应拦截 */
        this.service.interceptors.response.use((response: AxiosResponse<any>) => {
						const userInfoStore = useUserStore();

						// 处理登录请求的响应
						if (response.config.url === '/user/login' && response.data.code === 200) {
								const token = response.data.data.token;
								if (token) {
										// 将 token 存储到 sessionStorage
										sessionStorage.setItem('token', token);
										// 更新 Pinia 的 userStore
										userInfoStore.setToken(token);
								}
						}

            switch (response.data.code) {
                case 200:
                    return response.data;
                case 500:
                    return response.data;
                case 99998:
                    layer.msg('会话超时, 请重新登录', { 
											icon : 2, 
											time : 2000,
											yes: function(){
												router.push('/login');
												layer.closeAll()
											}
										});
                    return response.data;
                default:
                    break;
            }
        }, error => { 
			if (error.response) { 
				switch (error.response.status) {  
					case 401:  
						// 401未授权，重定向到登录页面显示登录对话框  
						layer.msg('身份已失效，请重新登录', { 
							icon : 2, 
							time : 2000
						});
						router.push('/login');
						return error.response.data;
					default:  
						break;
				}  
			}else{
				return Promise.reject(error);  
			}
		})
  }

	/**
	 * 方法参数解析
	 * @param url 地址string 	localhost:8080/api/user/list
	 * @param params 参数object/any 	{ id: 123 }	?代表这个参数是可选的	any代表不考虑传值类型
	 * @param _object 变量{} 	{ custom: 'data' }	_代表变量或参数是"私有的"或"保护的"
	 * 参数使用
	 * 传url参数	get('localhost:8080/api/user/list')
	 * 传url和params参数	get('localhost:8080/api/user/list', { id: 123 })
	 * 传所有参数	get('localhost:8080/api/user/list', { id: 123 }, { custom: 'data' })
	 */


    /* GET 方法 */
    get<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.get(url, { params, ..._object })
    }
    /* POST 方法 */
    post<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.post(url, params, _object)
    }
    /* PUT 方法 */
    put<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.put(url, params, _object)
    }
    /* DELETE 方法 */
    delete<T>(url: string, params?: any, _object = {}): Promise<any> {
        return this.service.delete(url, { params, ..._object })
    }
}

//导出新实例对象HTTP
export default new Http(config)